
#pragma once

#include <Arduino.h>
#include <PCF8574.h>

#include "app_config.hpp"


extern PCF8574 ex_port1;
extern PCF8574 ex_port2;


void init_pcf8574();

u8 ex1_cache();

void write_ex1(u8 b);

u8 read_ex1();

void set_ex1(u8 set_mask, u8 clear_mask);

bool test_ex1(u8 mask);

inline bool test_ex1_pin(u8 pin_num) {
    return test_ex1(static_cast<u8>(_BV(pin_num)));
}


enum class ad_channel {
    _0 = 0b000,
    _1,
    _2,
    _3,
    _4,
    _5,
    _6,
    _7,

    battery = _7,  // 电池电压通道
};


constexpr float AD_ATTENUATION_FACTOR = 5.0;                          // 衰减器的倍数
constexpr float AD_FACTOR = AD_ATTENUATION_FACTOR * 1000.0 / 1023.0;  // AD 转换值换算到电压的系数，单位毫伏

constexpr int AD_SWITCH_DELAY_US = 10;  // 切换通道后的延时时间

constexpr u8 BATTERY_MEASURE_WINDOW_SIZE = 8;    // 电池电压滤波器的窗口大小
constexpr TimeType BATTERY_MEASURE_PEROID = 53;  // 电池电压测量周期


void set_ad_channel(ad_channel as);

float read_voltage();

float read_ad_cache();

TimeType task_test_ad_channel_switch();

void init_battery_measure();

TimeType task_battery_measure();

float battery_voltage();